home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / BORLAND TURBO / GDIPRINT.PAK / FILENEW.C < prev    next >
C/C++ Source or Header  |  1997-05-05  |  19KB  |  581 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993 - 1995  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE:   filenew.c
  9. //
  10. //  PURPOSE:   Displays the "File New" dialog box
  11. //
  12. //  FUNCTIONS:
  13. //    CmdNew               - Displays the "File New" dialog box
  14. //    FileNew              - Processes messages for "File New" dialog box.
  15. //    MsgFileNewInit       - To initialize the File New dialog box
  16. //    MsgFileNewCommand    - Process WM_COMMAND message sent to the FileNew box. 
  17. //    CmdFileNewEditNotify - Validate bitmap size entered in File New dialog box.
  18. //    CmdFileNewDone       - Free the File New dialog box.
  19. //                      
  20. //  COMMENTS:
  21. //
  22. //
  23.  
  24. #include <windows.h>            // required for all Windows applications
  25. #include <windowsx.h>   
  26. #include <commctrl.h>           // prototypes and structure for the common controls.
  27.  
  28. #include "globals.h"            // prototypes specific to this application  
  29. #include "toolbar.h"
  30. #include "statbar.h"  
  31. #include "palette.h"
  32. #include "dibutil.h"
  33. #include "resource.h"
  34.  
  35. LRESULT CALLBACK FileNew(HWND, UINT, WPARAM, LPARAM);
  36. LRESULT MsgFileNewInit(HWND, UINT, WPARAM, LPARAM);
  37. LRESULT MsgFileNewCommand(HWND, UINT, WPARAM, LPARAM);
  38. LRESULT CmdFileNewEditNotify(HWND, WORD, WORD, HWND);
  39. LRESULT CmdFileNewDone(HWND, WORD, WORD, HWND);
  40.  
  41. // FileNew dialog message table definition.
  42. MSD rgmsdFileNew[] =
  43. {
  44.     {WM_COMMAND,    MsgFileNewCommand},
  45.     {WM_INITDIALOG, MsgFileNewInit}
  46. };
  47.  
  48. MSDI msdiFileNew =
  49. {
  50.     sizeof(rgmsdFileNew) / sizeof(MSD),
  51.     rgmsdFileNew,
  52.     edwpNone
  53. };
  54.  
  55. // FileNew dialog command table definition.
  56. CMD rgcmdFileNew[] =
  57. {
  58.     {IDD_WIDTH,  CmdFileNewEditNotify},
  59.     {IDD_HEIGHT, CmdFileNewEditNotify},
  60.     {IDOK,       CmdFileNewDone},
  61.     {IDCANCEL,   CmdFileNewDone}
  62. };
  63.  
  64. CMDI cmdiFileNew =
  65. {
  66.     sizeof(rgcmdFileNew) / sizeof(CMD),
  67.     rgcmdFileNew,
  68.     edwpNone
  69. };
  70.  
  71. // Module specific "globals"  Used when a variable needs to be
  72. // accessed in more than on handler function.
  73.          
  74. // some arbitrary bitmap sizes                           
  75. #define DEFBITMAPSIZE 256                 // default bitmap width or height
  76. #define MAXBITMAPSIZE 2048                // maximum allowable width or height
  77. #define NOBITMAPSIZE  (MAXBITMAPSIZE + 1) // width or height edit control empty
  78.          
  79. // specification for new bitmap
  80. UINT cxNewWidth;
  81. UINT cyNewHeight;
  82. UINT uNewBitsPerPixel;
  83.  
  84. // flag to prevent recursion in FileNewEditNotify
  85. BOOL fInEditNotify = FALSE;
  86.  
  87. //
  88. //  FUNCTION: CmdNew(HWND, WORD, WORD, HWND)
  89. //
  90. //  PURPOSE: Call the open common dialog and show its results.
  91. //
  92. //  PARAMETERS:
  93. //    hwnd     - The window handle.
  94. //    wCommand - IDM_FILENEW
  95. //    wNotify  - Notification number (unused)
  96. //    hwndCtrl - NULL (Unused)
  97. //
  98. //  RETURN VALUE:
  99. //    Always returns 0 - command handled.
  100. //
  101. //  COMMENTS:
  102. //    To process the IDM_FILENEW message, call DialogBox() to display the
  103. //    FileNew dialog box.
  104. //
  105.  
  106. #pragma argsused
  107. LRESULT CmdNew(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  108. {
  109.     HDC hdc;    
  110.     LPBITMAPINFOHEADER lpbih;    
  111.     char szBuffer[50];   
  112.      int  cbWritten;
  113.      int nResult;
  114.      int nNumColors;         // number of colors supposed to be in color table
  115.     int nColorsInTable;     // actual number of colors in color table
  116.     HDIB hDIBNew;    
  117.     LPRGBQUAD lpColorTable;    
  118.     HPALETTE hPalNew = NULL;
  119.     
  120.      cbWritten = LoadString(hInst, wCommand, szBuffer, sizeof(szBuffer));
  121.     if(cbWritten == 0)
  122.         lstrcpy(szBuffer, "Unknown Command");        
  123.     UpdateStatusBar(szBuffer, 0, 0);
  124.  
  125.     // prompt user if there is an existing bitmap with changes
  126.     nResult = QuerySaveChanges(hwnd);
  127.     if (nResult == IDCANCEL)
  128.         goto ErrExit;
  129.     
  130.     // put up dialog asking for parameters    
  131.     nResult = DialogBox(hInst, "FileNew", hwnd, (DLGPROC)FileNew);
  132.      if (!nResult)
  133.         goto ErrExit;  
  134.                                          
  135.     if (uNewBitsPerPixel > 8) 
  136.         // no color table if greater than 8 bpp
  137.         nNumColors = 0;
  138.     else  
  139.         // set number of colors in color table
  140.         nNumColors = 1 << uNewBitsPerPixel;                
  141.         
  142.     // Allocate memory for header & color table (if needed)
  143.     hDIBNew = GlobalAlloc(GHND, (DWORD)(sizeof(BITMAPINFOHEADER) +
  144.           nNumColors * sizeof(RGBQUAD)));
  145.  
  146.     if (!hDIBNew)
  147.     {    
  148.         DIBError(ERR_MEMORY);
  149.         goto ErrExit;
  150.     }
  151.  
  152.     lpbih = (LPBITMAPINFOHEADER)GlobalLock(hDIBNew);
  153.     if (!lpbih)
  154.     {
  155.         DIBError(ERR_LOCK);
  156.           goto ErrExitFree;
  157.     }
  158.           
  159.     // initialize bitmap header
  160.     lpbih->biSize = sizeof(BITMAPINFOHEADER);
  161.     lpbih->biWidth = cxNewWidth;      
  162.     lpbih->biHeight = cyNewHeight;       
  163.     lpbih->biPlanes = 1;              // must be 1
  164.      lpbih->biBitCount = (WORD) uNewBitsPerPixel;
  165.     lpbih->biCompression = BI_RGB;    
  166.     lpbih->biSizeImage = WIDTHBYTES((DWORD)lpbih->biWidth * 
  167.         (DWORD)lpbih->biBitCount) * lpbih->biHeight;
  168.      lpbih->biXPelsPerMeter = 0;
  169.     lpbih->biYPelsPerMeter = 0;
  170.     lpbih->biClrUsed = nNumColors;        
  171.     lpbih->biClrImportant = 0; 
  172.  
  173.     if (nNumColors)
  174.     {
  175.         if (bPalDevice)
  176.         {
  177.             HDC hdc;
  178.  
  179.             hdc = GetDC(hwnd);
  180.                 hPalNew = CreateHalftonePalette(hdc);
  181.             ReleaseDC(hwnd, hdc);
  182.         }
  183.         
  184.         // fill the color table from the logical palette
  185.         lpColorTable = (LPRGBQUAD)((LPSTR)(lpbih) + lpbih->biSize);
  186.         nColorsInTable = FillColorTable(hwnd,
  187.                                         lpColorTable,
  188.                                         hPalNew,
  189.                                         nNumColors);
  190.     
  191.         if (nColorsInTable == 0)
  192.           {
  193.             // unable to store any color values
  194.             DIBError(ERR_FILLCOLORTABLE);
  195.             goto ErrExitUnlock;  
  196.         }
  197.         else if (nColorsInTable != nNumColors)
  198.             lpbih->biClrUsed = nColorsInTable;
  199.     }
  200.      
  201.     // we've reached the point of no return (no undo)
  202.     // remove the existing DIB section
  203.     RemoveDIBSection(); 
  204.  
  205.     // set global variable to new DIB header    
  206.     hDIBInfo = hDIBNew;
  207.       
  208.     // create new DIB section
  209.     hdc = GetDC(hWndClient);  
  210.     hBitmap = CreateDIBSection(hdc, (LPBITMAPINFO)lpbih, DIB_RGB_COLORS, 
  211.         &lpvBits, 0, 0L);
  212.     ReleaseDC(hWndClient, hdc);
  213.     
  214.     if (!hBitmap || !lpvBits)
  215.     {   
  216.           DIBError(ERR_CREATEDIBSECTION);
  217.          
  218.         if (hBitmap)            
  219.             DeleteObject(hBitmap); 
  220.             
  221.         // create default wash for palette
  222.         if (bPalDevice)
  223.         {
  224.             HDC hdc;
  225.  
  226.             hdc = GetDC(hwnd);
  227.             hPalette = CreateHalftonePalette(hdc);
  228.                 ReleaseDC(hwnd, hdc);
  229.         }
  230.                         
  231.         goto ErrExitUnlock;
  232.     } 
  233.     
  234.     // set global variable for palette
  235.     hPalette = hPalNew;
  236.     
  237.     // initialize the DIB section's bitmap surface and paint the display 
  238.     InitDIBSection(hWndClient);
  239.                         
  240.      LoadString(hInst, IDS_UNTITLED, szBuffer, sizeof(szBuffer));
  241.     SetWindowTitle(hwnd, szBuffer);
  242.  
  243.     // adjust the size of the client window to the size of the bitmap
  244.     SizeClientWindow(hwnd);
  245.           
  246.     // unlock the DIB header, but don't free it!
  247.     GlobalUnlock(hDIBInfo);     
  248.     
  249.     // update status of menu and toolbar                                                        
  250.     // note that it's possible to save a newly initialized bitmap
  251.     EnableMenuItem(hMenu, IDM_FILESAVE, MF_ENABLED);
  252.      SendMessage(hWndToolbar, TB_ENABLEBUTTON, IDM_FILESAVE, MAKELONG(TRUE, 0));
  253.     EnableMenuItem(hMenu, IDM_FILESAVEAS, MF_ENABLED);    
  254.     EnableMenuItem(hMenu, IDM_FILECLOSE, MF_ENABLED);
  255.     EnableMenuItem(hMenu, IDM_FILEPRINT, MF_ENABLED); 
  256.     SendMessage(hWndToolbar, TB_ENABLEBUTTON, IDM_FILEPRINT, MAKELONG(TRUE, 0));    
  257.     EnableMenuItem(hMenu, IDM_CLEAR, MF_ENABLED);
  258.     
  259.     // set the status bar text to original text     
  260.     UpdateStatusBar(SZDESCRIPTION, 0, 0);    
  261.     return 1;       
  262.  
  263. ErrExitUnlock:
  264.      // note: hDIBNew == hDIBInfo if failure occurred after CreateDIBSection call
  265.     GlobalUnlock(hDIBNew);    
  266.  
  267. ErrExitFree:
  268.     // note: hDIBNew == hDIBInfo if failure occurred after CreateDIBSection call    
  269.     GlobalFree(hDIBNew);
  270.               
  271. ErrExit:            
  272.     // set the status bar text to original text     
  273.     UpdateStatusBar(SZDESCRIPTION, 0, 0);
  274.     
  275.     return 0;
  276. }
  277.  
  278. //
  279. //  FUNCTION: FileNew(HWND, UINT, WPARAM, LPARAM)
  280. //
  281. //  PURPOSE:  Processes messages for "FileNew" dialog box.
  282. //
  283. //  PARAMETERS:
  284. //    hdlg - window handle of the dialog box
  285. //    wMessage - type of message
  286. //    wparam - message-specific information
  287. //    lparam - message-specific information
  288. //
  289. //  RETURN VALUE:
  290. //    TRUE - message handled
  291. //    FALSE - message not handled
  292. //
  293. //  COMMENTS:
  294. //     Display version information from the version section of the
  295. //     application resource.
  296. //
  297. //     Wait for user to click on "Ok" button, then close the dialog box.
  298. //
  299.  
  300. LRESULT CALLBACK FileNew(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam)
  301. {
  302.     return DispMessage(&msdiFileNew, hdlg, uMessage, wparam, lparam);
  303. }
  304.  
  305.  
  306. //
  307. //  FUNCTION: MsgFileNewInit(HWND, UINT, WPARAM, LPARAM)
  308. //
  309. //  PURPOSE: To initialize the FileNew box with version info from resources.
  310. //
  311. //  PARAMETERS:
  312. //    hwnd - The window handing the message.
  313. //    uMessage - The message number. (unused).
  314. //    wparam - Message specific data (unused).
  315. //    lparam - Message specific data (unused).
  316. //
  317. //  RETURN VALUE:
  318. //    Always returns 0 - message handled.
  319. //
  320. //  COMMENTS:
  321. //    Uses the version apis to retrieve version information for
  322. //    each of the static text boxes in the FileNew box.
  323. //
  324.  
  325. #pragma argsused
  326. LRESULT MsgFileNewInit(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam)
  327. {   
  328.     HDC hdc;
  329.     int nBitsPerPixel;      // number of color bits per pixel used by device
  330.     int nPlanes;            // number of color planes used by device
  331.     LONG lNumColors;        // number of colors displayed by device
  332.     int nBitsPerPixelID;    // dialog control for color resolution setting
  333.     
  334.     // set the icon of this dialog to the class icon
  335.     SendMessage(hdlg, WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon);
  336.         
  337.      // Center the dialog over the application window
  338.     CenterWindow(hdlg, GetWindow(hdlg, GW_OWNER));
  339.                            
  340.     // Get the color resolution used by the device driver
  341.     hdc = GetDC(hdlg);
  342.     nBitsPerPixel = GetDeviceCaps(hdc, BITSPIXEL);
  343.     nPlanes = GetDeviceCaps(hdc, PLANES);
  344.     ReleaseDC(hdlg, hdc);
  345.     
  346.     // calculate number of colors displayed by device
  347.     lNumColors = 1L << (nBitsPerPixel + nPlanes - 1);
  348.     
  349.      // Create default bitmap settings
  350.     cxNewWidth = DEFBITMAPSIZE;
  351.     cyNewHeight = DEFBITMAPSIZE;   
  352.     SetDlgItemInt(hdlg, IDD_WIDTH, DEFBITMAPSIZE, FALSE);
  353.     SetDlgItemInt(hdlg, IDD_HEIGHT, DEFBITMAPSIZE, FALSE);    
  354.             
  355.     if (lNumColors < (1 << 4))
  356.         // device displays less than 16 colors      
  357.         nBitsPerPixelID = IDD_1;      
  358.     else if (lNumColors < (1 << 8))
  359.         // device displays less than 256 colors
  360.         nBitsPerPixelID = IDD_4;
  361.      else if (lNumColors < (1L << 16))
  362.         // display device capability is less than 64K colors       
  363.         nBitsPerPixelID = IDD_8;
  364.     else if (lNumColors < (1L << 24))                  
  365.         // display device capability is less than 4M colors         
  366.         nBitsPerPixelID = IDD_16;          
  367.     else                        
  368.         // display device capability is at least 4M colors        
  369.         nBitsPerPixelID = IDD_24; 
  370.         
  371.     SendDlgItemMessage(hdlg, nBitsPerPixelID, BM_SETCHECK, 1, 0L);    
  372.  
  373.      return TRUE;
  374. }
  375.  
  376.  
  377. //
  378. //  FUNCTION: MsgFileNewCommand(HWND, UINT, WPARAM, LPARAM)
  379. //
  380. //  PURPOSE: Process WM_COMMAND message sent to the FileNew box.
  381. //
  382. //  PARAMETERS:
  383. //    hwnd - The window handing the message.
  384. //    uMessage - The message number. (unused).
  385. //    wparam - Message specific data (unused).
  386. //    lparam - Message specific data (unused).
  387. //
  388. //  RETURN VALUE:
  389. //    Always returns 0 - message handled.
  390. //
  391. //  COMMENTS:
  392. //    Uses this DipsCommand function defined in wndproc.c combined
  393. //    with the cmdiFileNew structure defined in this file to handle
  394. //    the command messages for the FileNew dialog box.
  395. //
  396.  
  397. #pragma argsused
  398. LRESULT MsgFileNewCommand(HWND   hwnd,
  399.                                 UINT   uMessage,
  400.                                 WPARAM wparam,
  401.                                 LPARAM lparam)
  402. {
  403.     return DispCommand(&cmdiFileNew, hwnd, wparam, lparam);
  404. }
  405.  
  406. //
  407. //  FUNCTION: CmdFileNewValidate(HWND, WORD, HWND)
  408. //
  409. //  PURPOSE: Validate characters for bitmap size entered in File New dialog
  410. //
  411. //  PARAMETERS:
  412. //    hwnd - The window handling the command.
  413. //    wCommand - The command to be handled (unused).
  414. //    hwndCtrl - NULL (unused).
  415. //
  416. //  RETURN VALUE:
  417. //    Always returns TRUE.
  418. //
  419. //  COMMENTS:
  420. //
  421. //
  422.  
  423. #pragma argsused
  424. LRESULT CmdFileNewEditNotify(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  425. {   
  426.     int nNumChars, nValue;
  427.     char szBuffer[5];
  428.     BOOL fTranslated;    
  429.  
  430.      if (wNotify != EN_UPDATE || fInEditNotify)
  431.         // ignore all other notifications except EN_UPDATE, and don't recurse!
  432.         return TRUE;        
  433.                       
  434.     // validate characters input into edit control
  435.     nNumChars = GetDlgItemText(hdlg, wCommand, szBuffer, 5);  
  436.     nValue = GetDlgItemInt(hdlg, wCommand, &fTranslated, FALSE);
  437.                                    
  438.     switch (wCommand)
  439.     {
  440.         case IDD_WIDTH:
  441.             if (nNumChars == 0)     
  442.                      // the Width edit control is empty
  443.                 cxNewWidth = NOBITMAPSIZE;     
  444.             else if (fTranslated && nValue <= MAXBITMAPSIZE)       
  445.                 // the user input a value in accepted range
  446.                 cxNewWidth = nValue;     
  447.             else 
  448.             {                            
  449.                 // bad user input, so reset to previous value  
  450.                 
  451.                 // first set the flag to prevent recursion
  452.                 fInEditNotify = TRUE;
  453.                 
  454.                      if (cxNewWidth == NOBITMAPSIZE)
  455.                     // previously the Width edit control was empty
  456.                     SetDlgItemText(hdlg, wCommand, "");
  457.                 else
  458.                     // previously the Width edit control had a value
  459.                     SetDlgItemInt(hdlg, wCommand, cxNewWidth, FALSE);
  460.                                      
  461.                 // clear the recursion flag
  462.                 fInEditNotify = FALSE;                    
  463.                                                      
  464.                 // notify the user
  465.                 MessageBeep((UINT)-1);      
  466.                 }
  467.             
  468.             break;       
  469.             
  470.         case IDD_HEIGHT:
  471.             if (nNumChars == 0)          
  472.                 // the Height edit control is empty
  473.                 cyNewHeight = NOBITMAPSIZE;             
  474.             else if (fTranslated && nValue <= MAXBITMAPSIZE)
  475.                 // accept the user input
  476.                 cyNewHeight = nValue;
  477.             else
  478.                 {
  479.                 // bad user input, so reset to previous value    
  480.        
  481.                 // first set the flag to prevent recursion
  482.                 fInEditNotify = TRUE;
  483.                                             
  484.                 if (cyNewHeight == NOBITMAPSIZE)
  485.                     // previously the Height edit control was empty
  486.                     SetDlgItemText(hdlg, wCommand, "");
  487.                 else                               
  488.                     // previously the Height edit control had a value
  489.                     SetDlgItemInt(hdlg, wCommand, cyNewHeight, FALSE); 
  490.  
  491.                 // clear the recursion flag
  492.                 fInEditNotify = FALSE;                    
  493.                 
  494.                 // notify the user
  495.                 MessageBeep((UINT)-1);           
  496.             }        
  497.             
  498.             break;
  499.             
  500.         default:
  501.             break;
  502.      }
  503.         
  504.     return TRUE;
  505. }
  506.        
  507. //
  508. //  FUNCTION: CmdFileNewDone(HWND, WORD, HWND)
  509. //
  510. //  PURPOSE: Free the FileNew box and related data.
  511. //
  512. //  PARAMETERS:
  513. //    hwnd - The window handling the command.
  514. //    wCommand - The command to be handled (unused).
  515. //    hwndCtrl - NULL (unused).
  516. //
  517. //  RETURN VALUE:
  518. //    Always returns TRUE.
  519. //
  520. //  COMMENTS:
  521. //    Calls EndDialog to finish the dialog session.
  522. //
  523.  
  524. #pragma argsused
  525. LRESULT CmdFileNewDone(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  526. {
  527.     switch (wCommand)
  528.     {
  529.         case IDOK:
  530.         {       
  531.             char szBuffer[40];
  532.             
  533.             // the edit controls are already validated, but could be empty  
  534.             
  535.             if (cxNewWidth == NOBITMAPSIZE)
  536.             {   
  537.                 LoadString(hInst, ERR_WIDTH, szBuffer, sizeof(szBuffer)); 
  538.                      MessageBox(hdlg, szBuffer, szAppName, MB_ICONHAND);
  539.                 SetFocus(GetDlgItem(hdlg, IDD_WIDTH));
  540.                 return TRUE;
  541.             }
  542.             
  543.             if (cyNewHeight == NOBITMAPSIZE)
  544.             {   
  545.                 LoadString(hInst, ERR_HEIGHT, szBuffer, sizeof(szBuffer));  
  546.                 MessageBox(hdlg, szBuffer, szAppName, MB_ICONHAND);
  547.                 SetFocus(GetDlgItem(hdlg, IDD_HEIGHT));
  548.                 return TRUE;
  549.             }                    
  550.  
  551.             // we have the bitmap size, now get the color resolution
  552.             if (SendDlgItemMessage(hdlg, IDD_1, BM_GETCHECK, 0, 0L))
  553.                 uNewBitsPerPixel = 1;
  554.             else if (SendDlgItemMessage(hdlg, IDD_4, BM_GETCHECK, 0, 0L))
  555.                 uNewBitsPerPixel = 4;            
  556.             else if (SendDlgItemMessage(hdlg, IDD_8, BM_GETCHECK, 0, 0L))
  557.                 uNewBitsPerPixel = 8;                                     
  558.             else if (SendDlgItemMessage(hdlg, IDD_16, BM_GETCHECK, 0, 0L))
  559.                 uNewBitsPerPixel = 16;                        
  560.             else
  561.                 uNewBitsPerPixel = 24;
  562.  
  563.              // exit the dialog
  564.             EndDialog(hdlg, TRUE);         
  565.             break;
  566.         }
  567.                 
  568.         case IDCANCEL:
  569.             // cancel the dialog
  570.             EndDialog(hdlg, FALSE);
  571.             break;
  572.             
  573.         default:
  574.                 break;
  575.     }
  576.     
  577.     return TRUE;
  578. }
  579.        
  580.  
  581.